package com.marketlive.system.config;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/*
(C) Copyright MarketLive. 2006. All rights reserved.
MarketLive is a trademark of MarketLive, Inc.
Warning: This computer program is protected by copyright law and international treaties.
Unauthorized reproduction or distribution of this program, or any portion of it, may result
in severe civil and criminal penalties, and will be prosecuted to the maximum extent
possible under the law.
*/

import org.apache.commons.lang.StringUtils;
import org.marketlive.system.config.IConfigurationBranch;
import org.marketlive.system.config.IConfigurationManager;
import org.marketlive.system.config.IConfigurationLeaf;
import org.marketlive.system.config.IConfigurationContext;

/**
 * Outputs the configuration to a string.
 */
public class ConfigurationToString {

    /**
     * Logger
     */
    private static Log log = LogFactory.getLog(ConfigurationToString.class);

    /**
     * Returns the concatenation of the context and root.
     * @param config the configuration to use
     * @return the concatenated string 
     */
    public static String toStringBuilder( IConfigurationManager config ) {
        StringBuffer out = new StringBuffer(1024);

        toStringBuilder(out, config.getContext(), 0);
        toStringBuilder(out, config.getRoot(), 0);

        return out.toString();
    }

    /**
     * Appends formatted <code>IConfigurationBranch</code> information to the provided <code>StringBuffer</code>.
     * @param out the <code>StringBuffer</code> to modify
     * @param branch the <code>IConfigurationBranch</code> to use as the source
     * @param indent the level of indentation to start at (0 relative)
     */
    public static void toStringBuilder( StringBuffer out, IConfigurationBranch branch, int indent ) {
    	out.append(".");		// start line with non-blank character; otherwise, System.out.println() strips out leading whitespace!
        indent(out, indent);
        out.append("+ BRANCH: " + branch.getName() + "\n");
        IConfigurationLeaf[] leaves = branch.getLeaves();
        for (int i=0; i<leaves.length;i++) {
            toStringBuilder(out, leaves[i], indent+2);
        }
        IConfigurationBranch[] branches = branch.getBranches();
        for (int i=0; i<branches.length;i++) {
            toStringBuilder(out, branches[i], indent+1);
        }
    }

    /**
     * Appends formatted <code>IConfigurationLeaf</code> information to the provided <code>StringBuffer</code>.
     * @param out the <code>StringBuffer</code> to modify
     * @param leaf the <code>IConfigurationLeaf</code> to use as the source
     * @param indent the level of indentation to start at (0 relative)
     */
    public static void toStringBuilder( final StringBuffer out, final IConfigurationLeaf leaf, final int indent) {
    	out.append(".");		// start line with non-blank character; otherwise, System.out.println() strips out leading whitespace!
        indent(out, indent);
        out.append("- " + leaf.getName() + " : " + leaf.getAsString() + "\n");
    }

    
    /**
     * Appends formatted <code>IConfigurationContext</code> information to the provided <code>StringBuffer</code>.
     * 
     * @param out the <code>StringBuffer</code> to modify
     * @param leaf the <code>IConfigurationContext</code> to use as the source
     * @param indent the level of indentation to start at (0 relative)
     */
    public static void toStringBuilder(final StringBuffer out, final IConfigurationContext context, final int indent) {
        out.append(StringUtils.repeat("  ", indent));
        out.append("= client: " + context.getClient() +"\n");
        out.append(StringUtils.repeat("  ", indent));
        out.append("= environment: " + context.getEnvironment() + "\n");
        out.append(StringUtils.repeat("  ", indent));
        out.append("= vm-type: " + context.getVmType() + "\n");
        out.append(StringUtils.repeat("  ", indent));
        out.append("= host: " + context.getHost() + "\n");
        out.append(StringUtils.repeat("  ", indent));
        out.append("= vm-id: " + context.getVmId() + "\n");
    }

    /**
     * Append indent level to <code>StringBuffer</code> specified.
     * @param out <code>StringBuffer</code> to modify
     * @param indent the number of indents to add to the output
     */
    private static void indent( final StringBuffer out, int indent) {
        out.append(StringUtils.repeat("  ", indent));
    }
}
/*
    [junit] ------------- Standard Output ---------------
    // without leading non-blank, indentation is lost during printing 
    //     within JUnit(it's still in the String(Buffer)!) 
    [junit] ++++++++++++++++++++++++++++++++
    [junit] + BRANCH: sub-branch
    [junit] - mno : 567
    [junit] + BRANCH: sub-sub-branch
    [junit] - xyz : 123
    [junit] - abc : 987
    [junit] ++++++++++++++++++++++++++++++++
    // with leading non-blank, indentation is preserved
    [junit] .+ BRANCH: sub-branch
    [junit] .    - mno : 567
    [junit] .  + BRANCH: sub-sub-branch
    [junit] .      - xyz : 123
    [junit] .      - abc : 987
    [junit] ++++++++++++++++++++++++++++++++

*/
